package com.tanhua.server.service;


import com.tanhua.commons.templates.OssTemplate;
import com.tanhua.domain.db.UserInfo;
import com.tanhua.domain.mongo.Publish;
import com.tanhua.domain.mongo.Visitors;
import com.tanhua.domain.vo.MovementsVo;
import com.tanhua.domain.vo.PageResult;
import com.tanhua.domain.vo.VisitorsVo;
import com.tanhua.dubbo.api.PublishApi;
import com.tanhua.dubbo.api.RecommendUserApi;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.dubbo.api.VisitorsApi;
import com.tanhua.server.interceptor.UserHolder;
import com.tanhua.server.utils.RelativeDateFormat;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.bson.types.ObjectId;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class MovementsService {

    @Autowired
    private OssTemplate ossTemplate;

    @Reference
    private PublishApi publishApi;

    @Reference
    private UserInfoApi userInfoApi;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Reference
    private VisitorsApi visitorsApi;

    @Reference
    private RecommendUserApi recommendUserApi;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Autowired
    private MovementsMQService movementsMQService;

    private final String FREEZE_KEY = "FREEZE_KEY_"; // 定义冻结状态的前缀

    /**
     * 动态-发布
     */
    public ResponseEntity<Object> saveMovements(Publish publish, MultipartFile[] imageContent) throws Exception {
        // 1.获取当前登录用户id
        Long userId = UserHolder.getUserId();

        // 获取当前账号状态并判断是否冻结登录功能
        Boolean freeze = redisTemplate.hasKey(FREEZE_KEY + userId);
        UserInfo userInfo = userInfoApi.findById(userId);
        String freezingRange = userInfo.getFreezingRange();
        if (!(freeze && "3".equals(freezingRange)) ) {

            // 2.上传图片到阿里云OSS
            if (imageContent != null && imageContent.length > 0) {
                List<String> urlList = new ArrayList<>();
                for (MultipartFile multipartFile : imageContent) {
                    String url = ossTemplate.upload(multipartFile.getOriginalFilename(), multipartFile.getInputStream());
                    urlList.add(url);
                }
                // 设置图片url
                publish.setMedias(urlList);
            }

            if ("3".equals(freezingRange)){
                userInfo.setUserStatus("1");
                userInfo.setFreezingRange("0");
                userInfo.setFreezingTime("0");
                userInfoApi.update(userInfo);
            }


            // 3.设置相关参数
            publish.setId(ObjectId.get());  // 手动设置主键ID，服务提供者会直接用该ID，而不会自动生成
            publish.setUserId(userId);
            publish.setCreated(System.currentTimeMillis());
            publish.setState(0); // 待审核

            // 4.调用服务提供者api保存动态信息
            publishApi.save(publish);

            // 5.发送动态审核的消息至RocketMQ
            rocketMQTemplate.convertAndSend("tanhua-publish", publish.getId().toString());

            // 6.发送评分数据消息到RocketMQ
            movementsMQService.sendMsg(publish.getId().toString(), 1);

            return ResponseEntity.ok(null);
        }

        return ResponseEntity.status(401).body("账号已被冻结，请联系管理员");
    }

    /**
     * 好友动态
     */
    public ResponseEntity<Object> queryPublishList(Integer page, Integer pagesize) {
        // 1.获取当前登录用户id
        Long userId = UserHolder.getUserId();

        // 2.调用服务提供者api查询好友动态列表
        PageResult pageResult = publishApi.findByTimeLine(page, pagesize, userId);

        // 3.调用公共方法，封装数据
        setMovementsVo(pageResult);

        return ResponseEntity.ok(pageResult);
    }

    /**
     * 推荐动态
     */
    public ResponseEntity<Object> queryRecommendPublishList(Integer page, Integer pagesize) {
        // 1.获取当前登录用户id
        Long userId = UserHolder.getUserId();

        // 2.查询redis的推荐数据
        PageResult pageResult = findByRecommend(page, pagesize);
        if (pageResult == null) {
            // 2.1 调用服务提供者api分页查询推荐动态列表
            pageResult = publishApi.queryRecommendPublishList(page, pagesize, userId);
        }

        // 3.调用公共方法，封装数据
        setMovementsVo(pageResult);

        return ResponseEntity.ok(pageResult);
    }

    /**
     * 从redis查询推荐动态数据
     *
     * @param page
     * @param pagesize
     * @return
     */
    private PageResult findByRecommend(Integer page, Integer pagesize) {

        // 1.拼接key
        String key = "QUANZI_PUBLISH_RECOMMEND_" + UserHolder.getUserId();

        // 2.根据key从redis查询推荐动态的pid集合，10,8,31,38,22,7,26,11,10,10
        String value = redisTemplate.opsForValue().get(key);
        if (StringUtils.isEmpty(value)) {
            return null;
        }

        // 3.将value拆分成数组
        String[] pids = value.split(",");

        // 4.将数组转为list集合
        List<Long> pidList = new ArrayList<>();
        for (String pid : pids) {
            pidList.add(Long.valueOf(pid));
        }

        // 5.调用服务提供者api，根据pid集合分页查询
        PageResult pageResult = publishApi.findByPidList(pidList, page, pagesize);

        return pageResult;
    }


    /**
     * 接口名称：用户动态
     */
    public ResponseEntity<Object> queryMyPublishList(Integer page, Integer pagesize, Long userId) {
        // 1.获取登录用户id
        if (userId == null) {
            // 如果未传入userId，就获取当前用户id
            userId = UserHolder.getUserId();
        }

        // 2.调用服务提供者分页查询该用户的个人动态
        PageResult pageResult = publishApi.queryMyPublishList(page, pagesize, userId);

        // 3.调用公共方法，设置返回结果
        setMovementsVo(pageResult);

        return ResponseEntity.ok(pageResult);
    }

    /**
     * 封装结果数据公共方法
     */
    private void setMovementsVo(PageResult pageResult) {

        // 获取当前页的数据
        List<Publish> publishList = (List<Publish>) pageResult.getItems();

        // 3.封装返回结果
        List<MovementsVo> voList = new ArrayList<>();

        if (publishList != null && publishList.size() > 0) {
            for (Publish publish : publishList) {
                // 3.1 创建vo
                MovementsVo vo = new MovementsVo();

                // 3.2 封装数据
                // 封装动态信息
                BeanUtils.copyProperties(publish, vo);
                // 封装用户详情信息
                UserInfo userInfo = userInfoApi.findById(publish.getUserId());
                if (userInfo != null) {
                    BeanUtils.copyProperties(userInfo, vo);
                    if (!StringUtils.isEmpty(userInfo.getTags())) {
                        String[] tags = userInfo.getTags().split(",");
                        vo.setTags(tags);
                    }
                }

                vo.setId(publish.getId().toString());
                if (publish.getMedias() != null) {
                    String[] medias = publish.getMedias().toArray(new String[]{});
                    vo.setImageContent(medias);
                }

                vo.setDistance("50米");
                // 格式化日期
                vo.setCreateDate(RelativeDateFormat.format(new Date(publish.getCreated())));

                // 判断是否对该动态点赞过
                String likeKey = "public_like_comment_" + UserHolder.getUserId() + "_" + publish.getId();
                if (redisTemplate.hasKey(likeKey)) {
                    vo.setHasLiked(1); // 已点赞
                } else {
                    vo.setHasLiked(0); // 未点赞
                }

                // 判断是否对该动态喜欢过
                String loveKey = "public_love_comment_" + UserHolder.getUserId() + "_" + publish.getId();
                if (redisTemplate.hasKey(loveKey)) {
                    vo.setHasLoved(1);  // 已喜欢
                } else {
                    vo.setHasLoved(0);  // 未喜欢
                }

                // 3.3 添加vo到voList
                voList.add(vo);
            }
        }

        // 4.重新设置pageResult中的items
        pageResult.setItems(voList);
    }

    /**
     * 单条动态
     */
    public ResponseEntity<Object> queryMovementsById(String id) {
        // 1.调用服务提供者api查询动态详情
        Publish publish = publishApi.findById(id);

        // 2.封装返回数据
        MovementsVo vo = new MovementsVo();

        // 封装数据
        // 封装动态信息
        BeanUtils.copyProperties(publish, vo);

        // 封装用户详情信息
        UserInfo userInfo = userInfoApi.findById(publish.getUserId());
        if (userInfo != null) {
            BeanUtils.copyProperties(userInfo, vo);
            if (!StringUtils.isEmpty(userInfo.getTags())) {
                String[] tags = userInfo.getTags().split(",");
                vo.setTags(tags);
            }
        }

        vo.setId(publish.getId().toString());
        if (publish.getMedias() != null) {
            String[] medias = publish.getMedias().toArray(new String[]{});
            vo.setImageContent(medias);
        }

        vo.setDistance("50米");
        // 格式化日期
        vo.setCreateDate(RelativeDateFormat.format(new Date(publish.getCreated())));

        // 判断是否对该动态点赞过
        String likeKey = "public_like_comment_" + UserHolder.getUserId() + "_" + publish.getId();
        if (redisTemplate.hasKey(likeKey)) {
            vo.setHasLiked(1); // 已点赞
        } else {
            vo.setHasLiked(0); // 未点赞
        }
        // 判断是否对该动态喜欢过
        String loveKey = "public_love_comment_" + UserHolder.getUserId() + "_" + publish.getId();
        if (redisTemplate.hasKey(loveKey)) {
            vo.setHasLoved(1);  // 已喜欢
        } else {
            vo.setHasLoved(0);  // 未喜欢
        }

        return ResponseEntity.ok(vo);
    }

    /**
     * 谁看过我
     */
    public ResponseEntity<Object> queryVisitors() {
        // 1.查询当前登录用户的id
        Long userId = UserHolder.getUserId();

        // 2.判断是否是第一次进入首页
        List<Visitors> visitorsList = null;
        String key = "visitors_" + userId;
        if (!redisTemplate.hasKey(key)) {
            // 如果不存在key，代表是第一次进入首页
            visitorsList = visitorsApi.queryVisitors(userId, 5);

        } else {
            // 非第一次进入首页
            // 获取上一次进入首页的时间
            Long lastTime = Long.valueOf(redisTemplate.opsForValue().get(key));
            visitorsList = visitorsApi.queryVisitors(userId, lastTime);
        }

        // 3.记录本次进入首页的时间到redis
        redisTemplate.opsForValue().set(key, System.currentTimeMillis() + "");

        // 4.封装返回数据
        List<VisitorsVo> voList = new ArrayList<>();

        if (visitorsList != null && visitorsList.size() > 0) {
            for (Visitors visitors : visitorsList) {
                // 4.1 创建vo
                VisitorsVo vo = new VisitorsVo();

                // 4.2 封装vo
                vo.setId(visitors.getVisitorUserId());

                // 根据访客id查询用户详情
                UserInfo userInfo = userInfoApi.findById(visitors.getVisitorUserId());
                if (userInfo != null) {
                    BeanUtils.copyProperties(userInfo, vo);
                    if (!StringUtils.isEmpty(userInfo.getTags())) {
                        vo.setTags(userInfo.getTags().split(","));
                    }
                }

                // 查询当前用户和访客的缘分值
                long score = recommendUserApi.queryScore(userId, visitors.getVisitorUserId());
                vo.setFateValue((int) score);

                // 4.3 添加vo到集合
                voList.add(vo);
            }
        }

        return ResponseEntity.ok(voList);
    }
}
